package com.web.webstart.business.controller;

import com.web.webstart.base.util.FileUtil;
import com.web.webstart.base.util.XaUtil;
import com.web.webstart.base.util.ZipUtils;
import com.web.webstart.base.util.jpa.WebUitl;
import com.web.webstart.base.util.result.XaResult;
import com.web.webstart.business.entity.Model;
import com.web.webstart.business.entity.Project;
import com.web.webstart.business.service.ModelService;
import com.web.webstart.business.service.ProjectService;
import com.web.webstart.business.service.XaVelocityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
import java.util.Set;

import static com.web.webstart.base.util.FileUtil.dealPath;

/**
 * @author eason.zt
 * @version V1.0
 * @Title: ModelController.java
 * @Package com.web.webstart.business.controller
 * @Description: 模型控制器
 * @date 2015年3月23日 下午1:00:00
 */
@Controller
@RequestMapping("model" )
public class ModelController {

    @Autowired
    private ModelService modelService;

    @Autowired
    private ProjectService projectService;

    @Autowired
    private XaVelocityService xaVelocityService;

    //static String PROJECTS_PATH = "D://template//projects//";
    static String PROJECTS_PATH = FileUtil.getProjectsPath();

    // public ModelController(){
    // //xaVelocityService.init("");
    // }

    /**
     * @param nextPage
     * @param pageSize
     * @param sortData
     * @param jsonFilter
     * @return
     * @Title: findModelPage
     * @Description: 分页查询model
     */
    @ResponseBody
    @RequestMapping(method = RequestMethod.GET)
    public XaResult<Page<Model>> findModelPage(
            @RequestParam(defaultValue = "0" ) Integer nextPage,
            @RequestParam(defaultValue = "10" ) Integer pageSize,
            String sortData, String jsonFilter) {
        Pageable pageable = WebUitl.buildPageRequest(nextPage, pageSize,
                sortData);
        Map<String, Object> filterParams = WebUitl.getParametersStartingWith(
                jsonFilter, "search_" );
        return modelService.findModelByFilter(filterParams, pageable);
    }

    /**
     * @param modelId
     * @return
     * @Title: findModelById
     * @Description: 根据ID查找单条实体
     */
    @ResponseBody
    @RequestMapping(value = "{modelId}", method = RequestMethod.GET)
    public XaResult<Model> findModelById(@PathVariable Long modelId) {
        return modelService.findModel(modelId);
    }

    /**
     * @param model
     * @return
     * @Title: save
     * @Description: 新增一条实体
     */
    @ResponseBody
    @RequestMapping(method = RequestMethod.POST)
    public XaResult<Model> save(@RequestBody Model model,
                                HttpServletRequest request) {
        Long userId = WebUitl.getCmsLoginedUserId(request);
        model.setCreateUser(userId);
        model.setModifyUser(userId);
        return modelService.createModel(model);
    }

    /**
     * @param model
     * @return
     * @Title: updateModel
     * @Description: 修改一条实体
     */
    @ResponseBody
    @RequestMapping(method = RequestMethod.PUT)
    public XaResult<Model> updateModel(@RequestBody Model model,
                                       HttpServletRequest request) {
        Long userId = WebUitl.getCmsLoginedUserId(request);
        model.setModifyUser(userId);
        return modelService.updateModel(model);
    }

    /**
     * @param modelId
     * @return
     * @Title: deleteModelById
     * @Description: 删除一个实体
     */
    @ResponseBody
    @RequestMapping(value = "{modelId}", method = RequestMethod.DELETE)
    public XaResult<Model> deleteModelById(@PathVariable Long modelId,
                                           HttpServletRequest request) {
        Long userId = WebUitl.getCmsLoginedUserId(request);
        return modelService.deleteModel(modelId, userId);
    }

    @ResponseBody
    @RequestMapping(value = "pub/{modelId}", method = RequestMethod.PUT)
    public XaResult<Model> publishModelById(@PathVariable Long modelId,
                                            HttpServletRequest request) {
        Long userId = WebUitl.getCmsLoginedUserId(request);
        return modelService.publishModel(modelId, userId);
    }

    /**
     * @Description: 同时发布多个模块
     * @author duandazhi
     * @date 2016/11/8 下午4:06
     * @param modelIds 多个模块的id,用,分割
     */
    @ResponseBody
    @RequestMapping(value = "publishProjectModes", method = RequestMethod.GET)
    public void publishProjectModes(
            @RequestParam(value = "modelIds" ) String modelIds,
            HttpServletRequest request,HttpServletResponse response) {
        String[] arr =  modelIds.split(",");
        Long modelId = Long.parseLong(arr[0].toString());
        Long projectId = modelService.findModel(modelId).getObject()
                .getProjectId();
        System.out.println(modelIds+"");
        OutputStream ops = null;
        try {
            ops = response.getOutputStream();
            Map<String, String> fm = null;
            fm = xaVelocityService.publishProjectModels(projectId, arr);
            if (XaUtil.isEmpty(fm)) {
                return;
            }
            //删除缓存目录的数据
            FileUtil.deleteAllFilesOfDir(new File(PROJECTS_PATH));

            Project prj = projectService.findProject(projectId).getObject();
            String root = PROJECTS_PATH + prj.getIdentify();
            FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/business/entity/" )));
            FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/business/controller/" )));
            FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/business/repository/" )));
            FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/business/service/impl/" )));
            FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/test/" )));
            FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/remote/vo/" )));
            FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/remote/controller/" )));
            FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/remote/service/impl/" )));
            Set<String> fset = fm.keySet();
            for (String fnkey : fset) {
                ProjectController.wirteToFile(prj.getIdentify().toLowerCase(), root, fnkey,
                        fm.get(fnkey));
            }
            String fileName = prj.getIdentify() + ".zip";
            try {
                ZipUtils.zip(root, PROJECTS_PATH + fileName);
            } catch (Exception e) {
                e.printStackTrace();
            }
            File zip = new File(PROJECTS_PATH + fileName);
            FileInputStream in = new FileInputStream(zip);
            byte[] buffer = new byte[(int) zip.length()];
            in.read(buffer);

            ops.write(buffer);
            response.setContentType("application/zip; charset=utf-8" );
            response.setHeader("Content-Disposition",
                    "attachment; filename=" + fileName);
            ops.flush();
            in.close();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (ops != null) {
                    ops.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @param modelId
     * @return
     * @Title: findModelById
     * @Description: 根据ID查找单条实体
     */
    @ResponseBody
    @RequestMapping(value = "{modelId}/publish/{type}", method = RequestMethod.GET)
    public void publicModel(HttpServletResponse response,
                            @PathVariable Long modelId,
                            @PathVariable String type) {
        Long projectId = modelService.findModel(modelId).getObject()
                .getProjectId();
        OutputStream ops = null;
        try {
            ops = response.getOutputStream();
            Map<String, String> fm = null;
            switch (type) {
                case "Model":
                    fm = xaVelocityService.publishModel(projectId, modelId);
                    break;
                case "Repository":
                    fm = xaVelocityService.publishRepository(projectId, modelId);
                    break;
                case "Service":
                    fm = xaVelocityService.publishService(projectId, modelId);
                    break;
                case "ServiceImpl":
                    fm = xaVelocityService.publishServiceImpl(projectId, modelId);
                    break;
                case "Controller":
                    fm = xaVelocityService.publishController(projectId, modelId);
                    break;
                case "Project":
                    /**
                     * @Description: 修改 发布
                     * @author duandazhi
                     * @date 2016/10/28 下午1:32
                     */
                    fm = xaVelocityService.publishProjectModels(projectId, new String[]{modelId+""});
            }
            if (XaUtil.isEmpty(fm)) {
                return;
            }
            //删除缓存目录的数据
            FileUtil.deleteAllFilesOfDir(new File(PROJECTS_PATH));

            if ("Project".equals(type)) {
                Project prj = projectService.findProject(projectId).getObject();
                String root = PROJECTS_PATH + prj.getIdentify();
                FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/business/entity/" )));
                FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/business/controller/" )));
                FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/business/repository/" )));
                FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/business/service/impl/" )));
                FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/test/" )));
                FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/remote/vo/" )));
                FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/remote/controller/" )));
                FileUtil.makeDir(new File(dealPath(root + "/com/web/" + prj.getIdentify().toLowerCase() + "/remote/service/impl/" )));
                Set<String> fset = fm.keySet();
                for (String fnkey : fset) {
                    ProjectController.wirteToFile(prj.getIdentify().toLowerCase(), root, fnkey,
                            fm.get(fnkey));
                }
                String fileName = prj.getIdentify() + ".zip";
                try {
                    ZipUtils.zip(root, PROJECTS_PATH + fileName);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                File zip = new File(PROJECTS_PATH + fileName);
                FileInputStream in = new FileInputStream(zip);
                byte[] buffer = new byte[(int) zip.length()];
                in.read(buffer);

                ops.write(buffer);
                response.setContentType("application/zip; charset=utf-8" );
                response.setHeader("Content-Disposition",
                        "attachment; filename=" + fileName);
                ops.flush();
                in.close();
            } else {
                String fileNam = fm.keySet().iterator().next();
                ops.write(fm.get(fileNam).getBytes());
                response.setContentType("text/plain; charset=utf-8" );
                response.setHeader("Content-Disposition", "attachment; filename="
                        + fileNam);
                ops.flush();
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (ops != null) {
                    ops.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
